use log::{Level, LevelFilter, Metadata, Record, SetLoggerError};
use std::fs::OpenOptions;
use std::io::{self, Write};
use std::path::Path;
use std::sync::Mutex;
use std::{fs, path::PathBuf};

// 自定义日志记录器
pub struct FileLogger {
    level: Level,
    log_file: Option<Mutex<fs::File>>,
    console_output: bool, // 新增字段：控制是否输出到控制台
}

impl FileLogger {
    pub fn new(level: Level, log_file_path: Option<&Path>, console_output: bool) -> Self {
        let log_file = log_file_path.and_then(|path| {
            // 确保日志目录存在
            if let Some(parent) = path.parent() {
                let _ = fs::create_dir_all(parent);
            }

            match OpenOptions::new().create(true).append(true).open(path) {
                Ok(file) => Some(Mutex::new(file)),
                Err(e) => {
                    eprintln!("Failed to open log file: {}", e);
                    None
                }
            }
        });

        FileLogger {
            level,
            log_file,
            console_output,
        }
    }
}

impl log::Log for FileLogger {
    fn enabled(&self, metadata: &Metadata) -> bool {
        metadata.level() <= self.level
    }

    fn log(&self, record: &Record) {
        if self.enabled(record.metadata()) {
            let now = chrono::Local::now();
            let timestamp = now.format("%Y-%m-%d %H:%M:%S%.3f");
            let log_message = format!(
                "[{}] {} [{}:{}] {}\n",
                timestamp,
                record.level(),
                record.file().unwrap_or("unknown"),
                record.line().unwrap_or(0),
                record.args()
            );

            // 仅当启用控制台输出时才打印到控制台
            if self.console_output {
                let _ = io::stdout().write_all(log_message.as_bytes());
            }

            // 写入文件（如果配置了日志文件）
            if let Some(file) = &self.log_file {
                if let Ok(mut file) = file.lock() {
                    let _ = file.write_all(log_message.as_bytes());
                }
            }
        }
    }

    fn flush(&self) {
        if let Some(file) = &self.log_file {
            if let Ok(mut file) = file.lock() {
                let _ = file.flush();
            }
        }
        // 仅当启用控制台输出时才刷新控制台
        if self.console_output {
            let _ = io::stdout().flush();
        }
    }
}

// 全局静态记录器
static LOGGER: FileLogger = FileLogger {
    level: Level::Info,
    log_file: None,
    console_output: true, // 默认全局记录器仍然输出到控制台，因为它没有文件输出
};

// 初始化日志系统
pub fn init(
    level: LevelFilter,
    log_file: Option<PathBuf>,
    console_output: bool,
) -> Result<(), SetLoggerError> {
    if let Some(path) = log_file.as_deref() {
        let logger = Box::new(FileLogger::new(Level::Debug, Some(path), console_output));
        log::set_boxed_logger(logger)?;
        log::set_max_level(level);
    } else {
        log::set_logger(&LOGGER)?;
        log::set_max_level(level);
    }
    Ok(())
}

// 实用函数，获取默认日志文件路径
pub fn get_default_log_path() -> PathBuf {
    let mut path = std::env::temp_dir();  // 使用系统临时目录
    path.push("logs");
    fs::create_dir_all(&path).unwrap_or_default();
    path.push("git-tools.log");
    path
}
